﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using IDT.Entity;
using System.Xml.Serialization;
using IDT.Dal;
using IDT.Downloader;
using log4net;
using Microsoft.Win32;

namespace IDT.Wpf.Watcher
{
    /// <summary>
    /// Interaction logic for DownloadImageWindow.xaml
    /// </summary>
    public partial class DatabaseManagementWindow : Window
    {
        private ImageDownloader imageDownloader;
        private CategoryCollection categories;

        private ILog logger = LogManager.GetLogger(typeof (MainWindow));

        public DatabaseManagementWindow()
        {
            InitializeComponent();
            ListBoxCategories.ItemsSource = CategoryCollection;
            ListBoxAlbums.ItemsSource = AlbumCollection;
            ButtonStart.IsEnabled = false;
        }

        public DatabaseManagementWindow(ImageDownloader imageDownloader) : this()
        {
            this.imageDownloader = imageDownloader;
        }

        public ObservableCollection<Category> CategoryCollection { get; } = new ObservableCollection<Category>();

        public ObservableCollection<Album> AlbumCollection { get; } = new ObservableCollection<Album>();

        private async void DoButtonStartLoaded(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.DefaultExt = "xml";
            dialog.Filter = "XML File|*.xml";

            if (dialog.ShowDialog(this).GetValueOrDefault())
            {
                XmlSerializer serializer = new XmlSerializer(typeof (CategoryCollection));
                categories = await Task.Run(() => serializer.Deserialize(dialog.OpenFile()) as CategoryCollection);
                await Task.Run(() =>
                {
                    Parallel.ForEach(categories, category =>
                    {
                        category.CategoryId = category.Albums[0].CategoryId;
                        Parallel.ForEach(category.Albums, album =>
                        {
                            album.Category = category;
                            album.AlbumCover.Album = album;
                            album.AlbumCoverUrl = album.AlbumCover.Url;

                            Parallel.ForEach(album.Photos, photo =>
                            {
                                photo.Album = album;
                                photo.AlbumId = album.AlbumId;
                                photo.PhotoId = album.Photos.IndexOf(photo) + 1;
                                photo.Name = $"{album.Name}({photo.PhotoId:D2}).jpg";
                            });
                        });
                    });
                });

                //string xmlpath = "temp.xml";
                //FileStream fs = new FileStream(xmlpath, FileMode.Create, FileAccess.Write);
                //serializer.Serialize(fs, categories);
                //fs.Close();

                ButtonStart.IsEnabled = true;
            }
        }

        private async void DoButtonStartClicked(object sender, RoutedEventArgs e)
        {
            try
            {
                ButtonStart.IsEnabled = false;
                ButtonLoad.IsEnabled = false;


                Database.SetInitializer(new DropCreateDatabaseAlways<ImagesContext>());
                ImagesContext imagesContext = new ImagesContext();
                imagesContext.Configuration.AutoDetectChangesEnabled = false;

                imagesContext.Categories.AddRange(categories);
                imagesContext.SaveChanges();

                await Task.Run(() =>
                {
                    Parallel.ForEach(categories, category =>
                    {
                        Parallel.ForEach(category.Albums,
                            album => { Parallel.ForEach(album.Photos, photo => { photo.AlbumKey = album.AlbumKey; }); });
                    });
                });

                ProgressBarCategoriesDownloaded.Maximum = categories.Count;

                foreach (Category category in categories)
                {
                    CategoryCollection.Add(category);
                    ProgressBarCategoriesDownloaded.Value++;
                    ProgressBarAlbumsDownloaded.Maximum = category.Albums.Count;
                    ProgressBarAlbumsDownloaded.Value = 0;

                    foreach (var album in category.Albums)
                    {
                        try
                        {
                            imagesContext.Photos.AddRange(album.Photos);
                            imagesContext.SaveChanges();
                            AlbumCollection.Add(album);
                            ProgressBarAlbumsDownloaded.Value++;
                            ListBoxAlbums.SelectedIndex = ListBoxAlbums.Items.Count - 1;
                            ListBoxAlbums.ScrollIntoView(ListBoxAlbums.SelectedItem);
                        }
                        catch (Exception ex)
                        {
                            logger.Error(album.Url, ex);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error("DoButtonStartClicked", ex);
            }
        }

        private void DoButtonClearClicked(object sender, RoutedEventArgs e)
        {
            CategoryCollection.Clear();
            AlbumCollection.Clear();
        }

        private void DoButtonCloseClicked(object sender, RoutedEventArgs e)
        {
            Close();
        }
    }
}